﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using BASIC_CORE.Domain.Mongodb.User;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace BASIC_REDIS_API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HomeController : ControllerBase
    {
        // GET: api/<HomeController>
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/<HomeController>/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/<HomeController>
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api/<HomeController>/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api/<HomeController>/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }

        /// <summary>
        /// 查询用户详情
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("/user.get")]
        public User GetUser(User input)
        {
            return new User()
            {
                Id = new Guid().ToString(),
                Name = "ZHY",
                Age = 18,
                UserName = "153****2995",
                Password = "********"
            };
        }

        /// <summary>
        /// 获取首字母
        /// </summary>
        /// <param name="cnStr"></param>
        /// <returns></returns>
        [HttpPost("/spell")]
        public IActionResult GetSpellName(string cnStr)
        {
            string str = NPinyin.Pinyin.GetInitials(cnStr);
            // string str = cnStr.Substring(0, 6);
            return Ok(str);
        }

        /// <summary>
        /// 获取首字母(截取)
        /// </summary>
        /// <param name="cnStr"></param>
        /// <returns></returns>
        [HttpPost("GetInitials")]
        public IActionResult GetInitials(string cnStr)
        {
            cnStr = cnStr.Trim();
            StringBuilder chars = new StringBuilder();
            for (var i = 0; i < cnStr.Length; ++i)
            {
                string py = NPinyin.Pinyin.GetPinyin(cnStr[i]);
                if (py != "") chars.Append(py[0]);
            }

            return Ok(chars.ToString().ToUpper());
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        [HttpPost("GetMD5")]
        public IActionResult GetMD5(string str)
        {
            var text = "37f5456";
            var txt1 = text.Substring(0, 3);
            var txt2 = text.Substring(text.Length - 4, 4);

            string msg = $"欢迎您使用优家系统，请访问 http://qa-bsam.youzy.cn/store/info?id={txt2} 进行部署 ";
            return Ok(msg);
            //return Ok(Convert.ToBase64String(Encoding.UTF8.GetBytes(str)));
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        [HttpPost("GetMd5Decrypt")]
        public IActionResult GetMd5Decrypt(string str)
        {
            return Ok(Encoding.UTF8.GetString(Convert.FromBase64String(str)));
        }

        /// <summary>
        /// 使用AES加密字符串
        /// </summary>
        /// <param name="content">加密内容</param>
        /// <param name="key">秘钥</param>
        /// <returns>Base64字符串结果</returns>
        [HttpPost("GetEncrypt")]
        public IActionResult Encrypt(string content, string key)
        {
            byte[] keyArray = Encoding.UTF8.GetBytes(key);
            byte[] toEncryptArray = Encoding.UTF8.GetBytes(content);
            SymmetricAlgorithm des = Aes.Create();
            des.Key = keyArray;
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = des.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            return Ok(Convert.ToBase64String(resultArray));
        }

        /// <summary>
        /// 使用AES解密字符串
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="key">秘钥</param>
        /// <returns>UTF8解密结果</returns>
        [HttpPost("GetDecrypt")]
        public IActionResult Decrypt(string content, string key)
        {
            byte[] keyArray = Encoding.UTF8.GetBytes(key);
            byte[] toEncryptArray = Convert.FromBase64String(content);

            SymmetricAlgorithm des = Aes.Create();
            des.Key = keyArray;
            des.Mode = CipherMode.ECB;
            des.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = des.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Ok(Encoding.UTF8.GetString(resultArray));
        }

        /// <summary>
        /// 计算日期时间差
        /// </summary>
        /// <param name="date1"></param>
        /// <param name="date2"></param>
        /// <returns></returns>
        [HttpPost("DateDuration")]
        public IActionResult Duration(string date1, string date2)
        {
            TimeSpan time = Convert.ToDateTime(date1).Subtract(Convert.ToDateTime(date2)).Duration();
            var totalCount = time.Days;
            return Ok(totalCount);
        }


        /// <summary>
        /// RSA 私钥格式转换，.net->java    
        /// </summary>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        [HttpPost("RSA")]
        public IActionResult RSA(string privateKey)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(privateKey);
            BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
            BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
            BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
            BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
            BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
            BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
            BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
            BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));

            RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);

            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
            byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
            return Ok(Convert.ToBase64String(serializedPrivateBytes));
        }

        /// <summary>
        /// HMACSHA256 签名
        /// </summary>
        /// <param name="message"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        private static string Create(string message, string secret)
        {
            secret = secret ?? "";
            // var encoding = new System.Text.ASCIIEncoding(); 
            //byte[] keyByte = encoding.GetBytes(secret);
            //byte[] messageBytes = encoding.GetBytes(message);
            byte[] keyByte = Encoding.UTF8.GetBytes(secret);
            byte[] messageBytes = Encoding.UTF8.GetBytes(message);

            using (var hmacsha256 = new HMACSHA256(keyByte))
            {
                var hashmessage = hmacsha256.ComputeHash(messageBytes);
                var shas = SHA256Hex(hashmessage);
                var text = Encoding.UTF8.GetBytes(shas);
                return Convert.ToBase64String(Encoding.UTF8.GetBytes(shas));
            }
        }


        public static string SHA256Hex(byte[] s)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < s.Length; ++i)
            {
                builder.Append(s[i].ToString("x2"));
            }
            return builder.ToString();
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        [HttpPost("Encode")]
        public IActionResult Encode(string str, string key)
        {
            if (string.IsNullOrEmpty(str)) return null;
            Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str);

            RijndaelManaged rm = new RijndaelManaged
            {
                Key = Encoding.UTF8.GetBytes(key),
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7,
            };

            ICryptoTransform cTransform = rm.CreateEncryptor();
            Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            return Ok(Convert.ToBase64String(resultArray, 0, resultArray.Length));
            //return Ok(Create(str, ""));
        }

        /// <summary>
        /// 时间差
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        [HttpPost("Decode")]
        public IActionResult Decode(string text)
        {
            var date1 = Convert.ToDateTime(text);
            var date2 = DateTime.Now;
            var month = (date1.Year - date2.Year) * 12 + (date1.Month - date2.Month);

            return Ok(month);
        }

        /// <summary>
        /// 去特殊符号
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        [HttpPost("ReplaceChat")]
        public IActionResult ReplaceChatStr(string str)
        {
            //str = ReplaceChat(str);
            str = Extensions.ReplaceCharsByEmpty(str);
            str = str.ToLower();

            return Ok(str);
        }

        /// <summary>
        /// 获取月份天数
        /// </summary>
        /// <param name="year"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        [HttpPost("GetDays")]
        public IActionResult GetDays(int year, int month)
        {
            var days = System.Threading.Thread.CurrentThread.CurrentUICulture.Calendar.GetDaysInMonth(year, month);
            return Ok(days);
        }

        /// <summary>
        /// 时间格式化
        /// </summary>
        /// <param name="hour"></param>
        /// <returns></returns>
        [HttpPost("HourString")]
        public IActionResult HourString(int hour)
        {
            //string date = $"{DateTime.Now.ToString("yyyy-MM-dd")} {hour}:00";
            string date = $"{hour}:00";

            return Ok(Convert.ToDateTime(date).ToString("HH:mm"));
        }


        /// <summary>
        /// 计算两个日期的时间间隔
        /// </summary>
        /// <param name="DateTime1">第一个日期和时间</param>
        /// <param name="DateTime2">第二个日期和时间</param>
        /// <returns></returns>
        [HttpPost("DateDiff")]
        public IActionResult DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            var s = DateTime2.Subtract(DateTime1).TotalHours;

            return Ok(Convert.ToInt32(s));
        }

        /// <summary>
        /// 读取文本
        /// </summary>
        /// <param name="file"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        [HttpPost("GetTxt")]
        public IActionResult GetTxt(IFormFile file, int time)
        {
            DataSet ds = new DataSet();
            DataTable dt = new DataTable($"{time}ms慢查询日志");

            using (StreamReader reader = new StreamReader(file.OpenReadStream()))
            {
                dt.Columns.Add(new DataColumn("Date", typeof(string)));
                dt.Columns.Add(new DataColumn("Content", typeof(string)));
                string strRead;
                bool flag = true;
                while (flag)
                {
                    strRead = reader.ReadLine();
                    if (!string.IsNullOrEmpty(strRead))
                    {
                        var contentTimes = strRead.Split(" ");
                        var cTimes = contentTimes[contentTimes.Length - 1].ToString().Split("ms");
                        var cTime = Convert.ToInt32(cTimes[0]);
                        if (cTime > time)
                        {
                            DataRow dr = dt.NewRow();
                            var dates = strRead.Split("  ");
                            dr["Date"] = dates[0];
                            dr["Content"] = dates[1];
                            dt.Rows.Add(dr);
                        }
                    }
                    else
                    {
                        flag = false;
                    }
                }
                ds.Tables.Add(dt);
            }

            if (ds.Tables.Count > 0)
                ExportExcelFile(dt, "C:/Users/zhy/Desktop/日志/", $"大于{time}ms日志");

            return Ok("OK");
        }

        /// <summary>
        /// 将DataTable导出到Txt文件
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="path"></param>
        /// <param name="name"></param>
        public static void ExportExcelFile(DataTable dt,string path,string name)
        {
            //获取配置文件中导出txt文件路径(注：根据自己的实际情况获取路径)
            string strFilePath = path;
            if (!Directory.Exists(strFilePath))
                Directory.CreateDirectory(strFilePath);
            //整合文件名称 文件夹路径+时间文件名称
            string fileFullName = String.Format("{0}{1}.txt", strFilePath, name);

            //读取文件信息
            var fi = new FileInfo(fileFullName);
            //判断文件目录是否存在
            if (!fi.Directory.Exists)
            {
                fi.Directory.Create();
            }
            //FileMode.Append(打开文件，流指向文件的末尾，只能与枚举FileAccess.Write联合使用) FileAccess.Write(打开文件，用于只写)
            var fs = new FileStream(fileFullName, FileMode.Append, FileAccess.Write);            //StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);           
                                                                                                 //将字符串写入文件
            var sw = new StreamWriter(fs, Encoding.UTF8);
            var data = "";
            int s = 0;
            //写出列名称     
            if (s == 0)
            {
                ++s;
                for (var i = 0; i < dt.Columns.Count; i++)
                {
                    data += dt.Columns[i].ColumnName;
                    if (i < dt.Columns.Count - 1)
                    {
                        data += ",";
                    }
                }
                //写入文件并换行
                sw.WriteLine(data);
            }

            //写出各行数据       
            for (var i = 0; i < dt.Rows.Count; i++)
            {
                data = "";
                for (var j = 0; j < dt.Columns.Count; j++)
                {
                    var str = dt.Rows[i][j].ToString();
                    //str = str.Replace("\"", "\"\""); //替换英文冒号 英文冒号需要换成两个冒号  
                    //if (str.Contains(',') || str.Contains('"') || str.Contains('\r') || str.Contains('\n')) //含逗号 冒号 换行符的需要放到引号中         
                    //{
                    //    str = string.Format("\"{0}\"", str);
                    //}
                    data += str;
                    if (j < dt.Columns.Count - 1)
                    {
                        data += ",";
                    }
                }
                sw.WriteLine(data);
            }
            sw.Close();
            fs.Close();
        }

        public static string ReplaceChat(string str)
        {
            string[] dd ={"◎", "■", "●", "№", "↑", "→", "↓" +
                          "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "+", "=", "|", "[", "]", "？", "~", "`", "," +
                          "！", "<", ">", "‰", "→", "←", "↑", "↓", "¤", "§", "＃", "＆", "＆", "＼", "≡", "≠" +
                          "≈", "∈", "∪", "∏", "∑", "∧", "∨", "⊥", "‖", "‖", "∠", "⊙", "≌", "≌", "√", "∝", "∞", "∮" +
                          "∫", "≯", "≮", "＞", "≥", "≤", "≠", "±", "＋", "÷", "×", "/" +
                          "╄", "╅", "╇", "┻", "┻", "┇", "┭", "┷", "┦", "┣", "┝", "┤", "┷", "┷", "┹", "╉", "╇", "【", "】" +
                          "┌", "├", "┬", "┼", "┍", "┕", "┗", "┏", "┅", "—" +
                          "〖", "〗", "←", "〓", "☆", "§", "□", "‰", "◇", "＾", "＠", "△", "▲", "＃", "℃", "※", "≈", "￠",",","，",
                          ".","。","/"};
            for (int i = 0; i < dd.Length; i++)
            {
                string tt = dd[i];
                str = str.Replace(tt, "");
            }
            return str;
        }
    }
}
